package com.test.demo.controller;

import com.test.demo.commons.ResponseResult;
import com.test.demo.commons.utils.MapperUtils;
import com.test.demo.commons.utils.OkHttpClientUtil;
import com.test.demo.domain.UmsAdmin;
import com.test.demo.dto.LoginInfo;
import com.test.demo.dto.LoginParam;
import com.test.demo.feign.ProfileFeign;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author 远 chards_
 * @date: 2020-02-25 12:11
 */
@CrossOrigin(origins = "*", maxAge = 3600,allowCredentials = "true")
@RestController
public class LoginController {

    @Resource(name = "userDetailsService")
    public UserDetailsService userDetailsService;

    private static  final  String URL_OAUTH_TOKEN="http://localhost:9000/oauth/token";

    @Value("${business.oauth2.grant_type}")
    public String oauth2GrantType;

    @Value("${business.oauth2.client_id}")
    public String oauth2ClientId;

    @Value("${business.oauth2.client_secret}")
    public String oauth2ClientSecret;
    @Resource
    public BCryptPasswordEncoder passwordEncoder;

    @Resource
    private ProfileFeign profileFeign;

    @Resource
    public TokenStore tokenStore;


    @PostMapping("/user/login")
    public ResponseResult<Map<String,Object>> login(@RequestBody LoginParam loginParam){
        //封装返回类结果
        Map<String,Object> result= new HashMap<>();
        //验证账号密码
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginParam.getUsername());
        if (userDetails == null|| !passwordEncoder.matches(loginParam.getPassword(),userDetails.getPassword())){
            return  new ResponseResult<Map<String, Object>>(ResponseResult.CodeStatus.FAIL,"账号或密码错误",null);
        }

        Map<String,String>params= new HashMap<>();
        params.put("username",loginParam.getUsername());
        params.put("password",loginParam.getPassword());
        params.put("grant_type",oauth2GrantType);
        params.put("client_id",oauth2ClientId);
        params.put("client_secret",oauth2ClientSecret);
        try {
            Response response = OkHttpClientUtil.getInstance().postData(URL_OAUTH_TOKEN, params);
            String jsonString = Objects.requireNonNull(response.body()).string();
            Map<String, Object> jsonMap = MapperUtils.json2map(jsonString);
            Object token = String.valueOf(jsonMap.get("access_token"));
            result.put("token",token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseResult<>(ResponseResult.CodeStatus.OK,"登录成功",result);
    }



    @GetMapping(value = "/user/info")
    public ResponseResult<LoginInfo> info() throws Exception {

        //获取已经认证的信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        //返回个人信息-> json字符串
        String json = profileFeign.info(authentication.getName());

        UmsAdmin umsAdmin = MapperUtils.json2pojoByTree(json, "data", UmsAdmin.class);

        //熔断之后的结果
        if (umsAdmin.getUsername()==null){
            return MapperUtils.json2pojo(json,ResponseResult.class);
        }
        //封装并返回结果
        LoginInfo loginInfo=new LoginInfo();
        loginInfo.setName(umsAdmin.getUsername());
        loginInfo.setAvator(umsAdmin.getIcon());
        return  new ResponseResult<LoginInfo>(ResponseResult.CodeStatus.OK,"获取用户信息",loginInfo);
    }


    @PostMapping(value = "/user/logout")
    public ResponseResult<Void> logout(HttpServletRequest request){

        //获取请求中的token
        String token = request.getParameter("access_token");
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
        tokenStore.removeAccessToken(oAuth2AccessToken);
        return  new ResponseResult<Void>(ResponseResult.CodeStatus.OK,"用户注销",null);
    }



}
